#include "gd32f10x.h"
#include "usart.h"


uint8_t U0_RXBUFF[U0_RXBUFF_SIZE];      //串口0接收缓冲区


/**
 * @brief   usart0初始化
 * @param[in]   bandrate   串口设置波特率。
 * @return  空
 * @note 
 */
void uart0_init(uint32_t bandrate)
{
    /* 1、先打开外设时钟、相应IO口时钟 */
    rcu_periph_clock_enable(RCU_USART0);   //打开usart0时钟
    rcu_periph_clock_enable(RCU_GPIOA);     //usart0用到PA9、PA10

    /* 2、配置usart0 IO口 PA9(TX) PA10(RX) */
    gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_10);  //配置为浮空输入
    gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);       //配置为推挽输出  //视频教程配置成GPIO_MODE_AF_PP

    /* 3、配置串口 */
    usart_deinit(USART0);   //先reset再去配置
    usart_baudrate_set(USART0, bandrate);   //设置波特率
    usart_parity_config(USART0, USART_PM_NONE);   //设置无校验
    usart_word_length_set(USART0, USART_WL_8BIT);// 设置8位数据位  //有校验时就是9位数据位
    usart_stop_bit_set(USART0, USART_STB_1BIT);  //设置无停止位
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);   //发送使能
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);     //接收使能
    usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);//接收配置成DMA

    /* 4、使能中断*/
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);   //设置中断优先级分组
    nvic_irq_enable(USART0_IRQn, 0, 0);    //使能总中断
    usart_interrupt_enable(USART0, USART_INT_IDLE);  //打开串口空闲中断
    
    /* 5、使能串口 */
    usart_enable(USART0);
}   

/**
 * @brief   DMA初始化
 * @param[in]   
 * @return  空
 * @note 
 */
void dma0_init(void)
{
    dma_parameter_struct dma0_init_struct;

    /* 1、打开DMAx外设时钟 查手册u0_rx用到的是DMA0 通道4 */
    rcu_periph_clock_enable(RCU_DMA0);

    /* 2、配置DMA */
    dma_deinit(DMA0, DMA_CH4);//先reset再配置
    dma0_init_struct.periph_addr = USART0 + 4;       //外设地址 //u0（接收）数据寄存器地址
    dma0_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;      // 按字节传输
    dma0_init_struct.memory_addr = (uint32_t)U0_RXBUFF;       
    dma0_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;      
    dma0_init_struct.number = U0_SINGLERX_LEN_MAX + 1; //本次DMA要接收多大数据量 //+1为了让DMA永远不产生完成中断           
    dma0_init_struct.priority = DMA_PRIORITY_HIGH;          //DMA通道的优先级 //DMA通道可以被多个外设使用
    dma0_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;   //是否递增 // 一直用串口接收 再DMA移动到buff
    dma0_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;   //接收缓冲器地址需要递增
    dma0_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;      //设置DMA方向
    dma_init(DMA0, DMA_CH4, &dma0_init_struct);
    dma_circulation_disable(DMA0, DMA_CH4); //关闭循环模式
    dma_channel_enable(DMA0, DMA_CH4);  //配置完把相应的通道打开
}





